package com.taxinfo.controller;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONNull;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.taxinfo.common.ClientSession;
import com.taxinfo.component.alert.MyAlert;
import com.taxinfo.config.ImageSrc;
import com.taxinfo.pojo.dto.*;
import com.taxinfo.pojo.vo.*;
import com.taxinfo.service.LoginService;
import com.taxinfo.service.StandardSubService;
import com.taxinfo.service.SubMatchingService;
import com.taxinfo.utils.*;
import com.taxinfo.view.dataImport.AccBalMapInfoTable;
import com.taxinfo.view.standard.StandardSubTable;
import com.taxinfo.view.subjectMatch.SubjectMatchTable;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SubMatchPageController extends BaseController implements Initializable {
    @FXML
    private SubMatchingService subMatchingService = (SubMatchingService) SpringUtil.getBean("SubMatchingServiceImpl");

    @FXML
    private StandardSubService standardSubService = (StandardSubService) SpringUtil.getBean("StandardSubServiceImpl");

    @FXML
    private LoginService service = (LoginService) SpringUtil.getBean("LoginServiceImpl");

    @FXML
    public TextField compSubName;
    @FXML
    public TextField subName;
    @FXML
    public ScrollPane scrollPane;
    @FXML
    public ComboBox comBoxMap;

    @FXML
    public Button subjectMapUpload;
    @FXML
    public Button subjectInitImp;
    @FXML
    public Button balMapImpImp;
    @FXML
    public Button subjectMapDownload;
    @FXML
    private ComboBox category;

    private SubjectMatchTable table;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        List<SubMatchingDto> dtoList = subMatchingService.selectAllData("","","","");
        table = new SubjectMatchTable(dtoList);
        scrollPane.setContent(table);
        LoginDto loginDto =(LoginDto) ClientSession.getAttribute("user");
        subjectMapUpload.setVisible(true);
        subjectInitImp.setVisible(true);
        balMapImpImp.setVisible(true);
        ContextMenu cxmenu = new ContextMenu();
        MenuItem subMatchChange = new MenuItem("科目匹配人工调整");
        //查看余额表匹配记录
        subMatchChange.setOnAction(event -> {

            Dialog<String> dialog = new Dialog<>();
            dialog.setTitle("科目匹配人工调整");
            dialog.setResizable(true);
            DialogPane pane = dialog.getDialogPane();
            pane.setPrefSize(400,250);
            Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
            stage.getIcons().add(new Image(ImageSrc.lOGO_PATH));
            GridPane gridPane = new GridPane();
            gridPane.setVgap(10);
            gridPane.setAlignment(Pos.CENTER);

            String compSubNo = table.getSelectedData().getCompSubNo();
            Label lCompSubNo = new Label("企业科目编号:");
            lCompSubNo.setAlignment(Pos.CENTER_RIGHT);
            gridPane.add(lCompSubNo,1,1);
            TextField tfCompSubNo = new TextField(compSubNo);
            tfCompSubNo.setPrefWidth(300);
            tfCompSubNo.setPrefHeight(30);
            tfCompSubNo.setEditable(false);
            gridPane.add(tfCompSubNo,2,1);

            String compSubName = table.getSelectedData().getCompSubName();
            Label lPasswd = new Label("企业科目名称:");
            lPasswd.setAlignment(Pos.CENTER_RIGHT);
            gridPane.add(lPasswd,1,2);
            TextField tfCompSubName = new TextField(compSubName);
            tfCompSubName.setPrefHeight(30);
            tfCompSubName.setPrefWidth(300);
            tfCompSubName.setEditable(false);
            gridPane.add(tfCompSubName,2,2);

            String subName = table.getSelectedData().getSubName();
            Label lSubName = new Label("标准科目名称:");
            lCompSubNo.setAlignment(Pos.CENTER_RIGHT);
            gridPane.add(lSubName,1,3);
            ComboBox<String> tfSubName = new ComboBox<>();
            //初始化CombBox
            tfSubName.setValue("全部信息");
            tfSubName.setEditable(true);
            tfSubName.setPrefHeight(30);
            tfSubName.setPrefWidth(300);
            gridPane.add(tfSubName,2,3);

            String subNo = table.getSelectedData().getSubNo();
            Label lSubNo = new Label("标准科目编号:");
            lCompSubNo.setAlignment(Pos.CENTER_RIGHT);
            gridPane.add(lSubNo,1,4);
            TextField tfSubNo = new TextField(subNo);
            tfSubNo.setPrefHeight(30);
            tfSubNo.setPrefWidth(300);
            tfSubNo.setEditable(false);
            gridPane.add(tfSubNo,2,4);

            String isUse = table.getSelectedData().getSwitchFlg();
            Label lIsUse = new Label("是否启用:");
            lIsUse.setStyle("-fx-padding: 0 0 0 27");
            lIsUse.setAlignment(Pos.CENTER_RIGHT);
            gridPane.add(lIsUse,1,5);
            CheckBox ckIsUse = new CheckBox();
            ckIsUse.setStyle("-fx-padding: 0 0 0 40");
            ckIsUse.setPrefHeight(30);
            ckIsUse.setPrefWidth(300);
            ckIsUse.setSelected("禁用".equals(isUse)?false:true);
            gridPane.add(ckIsUse,2,5);

            TextField tfHidderSubName = new TextField();
            tfHidderSubName.setVisible(false);
            gridPane.add(tfHidderSubName,2,4);

            pane.setContent(gridPane);
//            // 监听 ComboBox 的 TextField 的 onKeyPressed 事件
//            tfSubName.getEditor().setOnKeyPressed(event1 -> {
//                if (event1.getCode() == KeyCode.ENTER) {
//                    String selectedValue = tfSubName.getEditor().getText();
//                    String[] compSubName1  = getSpecialCharsBySplit(selectedValue);
//                    List<StandardSubDto> standardSubDtos =  standardSubService.selectMatchByKey(compSubName1[0], compSubName1[compSubName1.length-1]);
//                    tfSubName.getItems().clear();
//                    tfSubName.getItems().add("");
//                    standardSubDtos.forEach(standardSubDto->{
//                        tfSubName.getItems().addAll(standardSubDto.getSubName().concat(",").concat(standardSubDto.getSubNo()));
//                    });
//                }
//            });
//
//            // 监听 ComboBox 的 onAction 事件（回车键或选择项时触发）
//            tfSubName.setOnAction(event2 -> {
//                String selectedValue = tfSubName.getEditor().getText();
//                String[] compSubName1  = getSpecialCharsBySplit(selectedValue);
//                List<StandardSubDto> standardSubDtos =  standardSubService.selectMatchByKey(compSubName1[0], compSubName1[compSubName1.length-1]);
//                tfSubName.getItems().clear();
//                tfSubName.getItems().add("");
//                standardSubDtos.forEach(standardSubDto->{
//                    tfSubName.getItems().addAll(standardSubDto.getSubName().concat(",").concat(standardSubDto.getSubNo()));
//                });
//            });

            // 创建鼠标点击事件处理器
            EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                   QueryWrapper<StandardSub> queryWrapper = new QueryWrapper<>();
                    if(!StringUtils.isEmpty(tfSubName.getEditor().getText()) && !"全部信息".equals(tfSubName.getEditor().getText())){
                        queryWrapper.like("sub_name",tfSubName.getEditor().getText());
                        queryWrapper.eq("dec_type",table.getSelectedData().getDecType());
                        List<StandardSub>  standardSubs = standardSubService.list(queryWrapper);
                        standardSubs.forEach(standardSub->{
                            tfSubName.getItems().addAll(standardSub.getSubName().concat(",").concat(standardSub.getSubNo()));
                        });
                    }else{
                        String[] compSubName  = getSpecialCharsBySplit(tfCompSubName.getText().replaceAll("\\s",""));
                        List<StandardSubDto> standardSubDtos =  standardSubService.selectMatchByKey(compSubName[0], compSubName[compSubName.length-1],table.getSelectedData().getDecType());
                        tfSubName.getItems().clear();
                        tfSubName.getItems().add("");
                        standardSubDtos.forEach(standardSubDto->{
                            tfSubName.getItems().addAll(standardSubDto.getSubName().concat(",").concat(standardSubDto.getSubNo()));
                        });
                    }
                }
            };
            // 将事件处理器设置到按钮上
            tfSubName.setOnMouseClicked(eventHandler);

            tfSubName.valueProperty().addListener((observable, oldValue, newValue) -> {
                String[] selectedValue =newValue.split(",");
                tfHidderSubName.setText(selectedValue[0]);
                if(selectedValue.length>1){
                   tfSubNo.setText(selectedValue[1]);
                }
            });
            // 设置按钮和事件处理（可选）
            ButtonType buttonTypeOK = new ButtonType("确定");
            pane.getButtonTypes().add(buttonTypeOK);
            pane.getButtonTypes().add(ButtonType.CANCEL);
            dialog.setResultConverter(dialogButton -> dialogButton == buttonTypeOK ? "OK" : null);
            dialog.showAndWait().ifPresent(response -> {
                if ("OK".equals(response)) {
                    Wrapper wrapper = new QueryWrapper<SubMatching>().eq("comp_sub_no", tfCompSubNo.getText());
                    SubMatching subMatching = subMatchingService.getOne(wrapper);
                    subMatching.setSubName(tfHidderSubName.getText().trim());
                    subMatching.setSubNo(tfSubNo.getText().trim());

                    QueryWrapper queryWrapper = new QueryWrapper();
                    queryWrapper.eq("sub_no", tfSubNo.getText().trim());
                    StandardSub standardSub = standardSubService.getOne(queryWrapper);
                    if(null != standardSub){
                        subMatching.setSubType(standardSub.getSubType());
                    }
                    subMatching.setSwitchFlg(ckIsUse.isSelected()?"启用":"禁用");
                    subMatchingService.update(subMatching,wrapper);
                    this.findInfo();
                }
            });
        });

        // 将菜单项添加到ContextMenu中
        cxmenu.getItems().addAll(subMatchChange);
        scrollPane.setContextMenu(cxmenu);
        comBoxMap.getItems().addAll("全部","启用","禁用");
        comBoxMap.setValue("全部");

        category.getItems().addAll("全部","余额表科目","负债表科目","利润表科目");
        category.setValue("全部");
    }

    @FXML
    private void findInfo() {
        String isMatch = "";
        String sCondition = "";
        if (comBoxMap.getValue().equals("全部")) {
            sCondition = "";
        }else{
            sCondition =String.valueOf(comBoxMap.getValue());
        }

        String strCategory = "";
        if (category.getValue().equals("全部")) {
            strCategory = "";
        }else{
            strCategory =String.valueOf(category.getValue());
        }

        List<SubMatchingDto> dtoList = subMatchingService.selectAllData(compSubName.getText().trim(),subName.getText().trim(),sCondition,strCategory);
        table.clearData();
        if (dtoList != null && dtoList.size() > 0) {
             for (SubMatchingDto bean : dtoList){
                table.addBean(bean);
            }

        } else {
            new MyAlert(Alert.AlertType.INFORMATION, "没有找到您查找的标准科目信息！").show();
        }
    }

    @FXML
    private void subjectInit() {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("选择余额表文件");
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("余额表科目文件", "*.xls;*.xlsx"));
        File file = fileChooser.showOpenDialog(null); // 或者使用某个特定的Stage作为参数
        if (file != null) {
            String msg =  subMatchingService.initXlsx(file);
            if(StringUtils.isEmpty(msg)){
                new MyAlert(Alert.AlertType.INFORMATION, "余额表科目自动匹配完成，请核对匹配结果!").show();
            }else{
                new MyAlert(Alert.AlertType.ERROR, "余额表科目匹配失败，"+msg).show();
            }
            this.findInfo();
        }

    }
    @FXML
    private void balMapImp() {
        Map<String, List<String>> columnInfo =super.getColumnInfo("");
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("选择会计准则文件");
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("会计准则文件", "*.xls;*.xlsx"));
        File file = fileChooser.showOpenDialog(null); // 或者使用某个特定的Stage作为参数
        if (file != null) {
            String msg =  subMatchingService.initAccXlsx(file,columnInfo);
            if(com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(msg) && "0".equals(msg.substring(0,1))){
                new MyAlert(Alert.AlertType.WARNING, msg.substring(1)).show();
            }else if(com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(msg)){
                new MyAlert(Alert.AlertType.ERROR, "会计准则中企业科目匹配失败，"+msg).show();
            }else{
                new MyAlert(Alert.AlertType.INFORMATION, "会计准则中企业科目自动匹配完成，请核对匹配结果!").show();
            }
            this.findInfo();
        }
    }

    @FXML
    private void subjectMapImp() {
        FileChooser fileChooser = new FileChooser();
        // 设置初始目录，例如用户的文档目录
        fileChooser.setInitialDirectory(new File(System.getProperty("user.home") + "/Documents"));
        LoginDto loginDto =(LoginDto) ClientSession.getAttribute("user");
        fileChooser.setInitialFileName(loginDto.getCompanyName().concat("-科目匹配记录"));
        // 设置文件过滤器，例如只显示文本文件
        FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("xlsx files (*.xlsx)", "*.xlsx");
        fileChooser.getExtensionFilters().add(extFilter);
            // 显示另存为对话框
        File selectedFile = fileChooser.showSaveDialog(null);
        String targetFilePath = "";
        if (selectedFile != null) {
            targetFilePath = selectedFile.getPath();
            String msg = subMatchingService.exportSubMatchFile(targetFilePath);
            if(com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(msg)){
                new MyAlert(Alert.AlertType.ERROR, msg).show();
            }else{
                new MyAlert(Alert.AlertType.INFORMATION, "科目余额表映射记录导出成功.").show();
            }
        }

    }

    @FXML
    private void subjectMapDownload(){
        LoginDto loginDto =(LoginDto) ClientSession.getAttribute("user");
        HashMap<String, Object> request = new HashMap<String ,Object >();
        request.put("email", DesUtils.encrypt(loginDto.getId(), "Client_taxSw@9801",false));
        try {
            String rtnVal =  DesUtils.decrypt(service.getCertfyInfo(request),"Server_taxSw@9802",false);
            JSONObject json = new JSONObject(rtnVal);
            if(json.get("systemSubMatchingBOList") instanceof JSONNull) {
                ;
            }else{
                subMatchingService.getBaseMapper().delete(new QueryWrapper<>());
                JSONArray jsonArray = json.getJSONArray("systemSubMatchingBOList");
                List<SystemSubMatchingBO> systemSubMatchingBOS = jsonArray.toList(SystemSubMatchingBO.class);
                List<SubMatching> subMatchings = new ArrayList<>();
                systemSubMatchingBOS.forEach(systemSubMatchingBO -> {
                    SubMatching subMatching = new SubMatching();
                    if("0".equals(systemSubMatchingBO.getStatus())){
                        BeanUtils.copyProperties(systemSubMatchingBO,subMatching);
                        if(null != subMatching){
                            subMatchingService.insertMatch(subMatching);
                        }
                    }
                });
                new MyAlert(Alert.AlertType.INFORMATION, "标准科目映射关系获取成功。").show();
                this.findInfo();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @FXML
    private void subjectMapUpload(){
//        Dialog<String> dialog = new Dialog<>();
//        dialog.setTitle("匹配结果推送");
//        dialog.setResizable(true);
//        DialogPane pane = dialog.getDialogPane();
//        pane.setPrefSize(300,100);
//        Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
//        stage.getIcons().add(new Image(ImageSrc.lOGO_PATH));
//        GridPane gridPane = new GridPane();
//
//        Label lAccout = new Label("推送用户账号: ");
//        lAccout.setAlignment(Pos.CENTER);
//        gridPane.add(lAccout,1,1);
//        TextField tfAccout = new TextField();
//        tfAccout.setAlignment(Pos.CENTER_LEFT);
//        tfAccout.setPrefWidth(200);
//        tfAccout.setPrefHeight(30);
//        gridPane.add(tfAccout,2,1);
//        pane.setContent(gridPane);
//
//        // 设置按钮和事件处理（可选）
//        ButtonType buttonTypeOK = new ButtonType("确定");
//        pane.getButtonTypes().add(buttonTypeOK);
//        pane.getButtonTypes().add(ButtonType.CANCEL);
//        dialog.setResultConverter(dialogButton -> dialogButton == buttonTypeOK ? "OK" : null);
//        dialog.showAndWait().ifPresent(response -> {
//            if ("OK".equals(response)) {
//
//            }
//        });
//        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(tfAccout.getText())){
//            new MyAlert(Alert.AlertType.ERROR, "请输入用户账号").show();
//        }else{
//
//        }
        List<SubMatchingDto> subBaseMatchingDtos = subMatchingService.selectAllDataByStatus("0");
        LoginDto loginDto =(LoginDto) ClientSession.getAttribute("user");
        List<SystemBaseSubMatchingBO> subMatchRequestBaseDtos = new ArrayList<>();
        subBaseMatchingDtos.forEach(subMatchingDto -> {
            SystemBaseSubMatchingBO baseSubMatchingBO = new SystemBaseSubMatchingBO();
            BeanUtils.copyProperties(subMatchingDto, baseSubMatchingBO);
            baseSubMatchingBO.setSoftId(loginDto.getSoftId());
            subMatchRequestBaseDtos.add(baseSubMatchingBO);
        });

        List<SubMatchingDto> subMatchingUserDtos = subMatchingService.selectAllDataByStatus("1");
        List<SystemSubMatchingBO> subMatchRequestUserDtos = new ArrayList<>();
        subMatchingUserDtos.forEach(subMatchingDto -> {
            SystemSubMatchingBO subMatchRequestDto = new SystemSubMatchingBO();
            BeanUtils.copyProperties(subMatchingDto, subMatchRequestDto);
            subMatchRequestDto.setUserId(loginDto.getId());
            subMatchRequestUserDtos.add(subMatchRequestDto);
        });
        SystemSubMatchingList systemSubMatchingList = new SystemSubMatchingList();
        systemSubMatchingList.setSystemBaseSubMatchings(subMatchRequestBaseDtos);
        systemSubMatchingList.setSystemSubMatchings(subMatchRequestUserDtos);

        String rtnVal = subMatchingService.postList(systemSubMatchingList);
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(rtnVal)) {
            new MyAlert(Alert.AlertType.INFORMATION, "匹配数据推送完成,通知用户重新登录即可使用！").show();
        }
    }

    private String[] getSpecialCharsBySplit(String input){
        // 定义一个正则表达式，匹配非字母数字字符
        String regex = "[^\\p{Alpha}\\p{Digit}\\u4e00-\\u9fa5]";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);
        StringBuilder specialChars = new StringBuilder();
        String split = "";
        while (matcher.find()) {
            System.out.println("Special characters: " + matcher.group());
            split = matcher.group();
            System.out.println(" #@@@@@@@ = ".concat(split));
            if("\\".equals(matcher.group())){
                split = "\\\\";
            }
            break;
        }
        if("".equals(split)){
            return new String[]{input};
        }else{
            String[] rtnVal  = input.split(split);
            return rtnVal;
        }
    }

}
